﻿    using Sirius.WebSocket;
using static Sirius.WebSocket.SiriusWebSocketBase;
using System.Text.Json.Serialization;
using static Sirius.Log.Log;
using System.Net.WebSockets;
using static Sirius.Data.PackManager;
using System.Text.Json;
using Sirius.SiriusAPI;
using static Sirius.WebSocket.MessageManager.MessagePush;
using Sirius.SystemDll;
using Sirius.Application;
using Sirius.Util;
using System.Text;

namespace Sirius.Utils
{

        public static class Util
    {
        public static int s = 0;
        public static int intents = 0;//订阅事件
        public static string? HeartBeat_Data = null;//心跳数据
        public static System.Timers.Timer HeartartBeat_Timer;
        public static System.Timers.Timer Reconnect_Timer = new System.Timers.Timer(3000);

        //重连，重连失败则无限循环重连，直到成功为止，待优化
        public static void Reconnect()
        {
            HeartartBeat_Timer.Stop();
            int count = 0;
            Task.Run(async () =>
            {
                while (true)
                {
                    SiriusWebSocketClient.SiriusClient = new ClientWebSocket();
                    SiriusWebSocketClient.SiriusClientConnect();
                    count++;
                    Thread.Sleep(3000);
                    //if (HeartBeat_Data != null)
                    //{
                    //    Console.WriteLine("已释放内存");
                    //    LogSuc("Server", "SiriusClient已恢复连接!"); 
                    //    return;
                    //}
                    if (SiriusWebSocketClient.SiriusClient.State == WebSocketState.Open)
                    {
                        LogSuc("Server", "SiriusClient已恢复连接!");
                        HeartartBeat_Timer.Start();
                        return;
                    }
                    LogErr("Server", "重连失败,正在进行第" + count + "次重连...");
                }
            });
        }


        //发送重连包
        public static void Resume(string BotId,string Token,string session_id,string seq)
        {
            //判断SiriusClient状态是否未连接状态
            if(Sirius.WebSocket.SiriusWebSocketClient.SiriusClient.State != WebSocketState.Open)
            {
                Sirius.WebSocket.MessageManager.MessagePush.session_id = null;
                Sirius.WebSocket.SiriusWebSocketClient.SiriusClient = new ClientWebSocket();
                Sirius.WebSocket.SiriusWebSocketClient.SiriusClientConnect();
                LogSuc("重连", "会话ID失效，重新鉴权...");
            }
            else
            {
                SendMsg(SiriusWebSocketClient.SiriusClient, CreateResume($"{BotId}.{Token}", session_id, int.Parse(seq)));
            }
            
        }
        //事件订阅
        public static void intentsInit()
        {
            if (File.Exists("Config.json"))
            {
                LogOut("初始化", "订阅文件检测通过！");
                StreamReader sr = new StreamReader("Config.json");
                //读入文件，获取文件的所有内容
                string intentsJson = sr.ReadToEnd();
                var json = JsonDocument.Parse(intentsJson);//解析json
                var intentsArray = json.RootElement.GetProperty("intents").EnumerateArray();

                //枚举数组
                foreach (var element in intentsArray)
                {
                    var enumElementArray = element.EnumerateObject();//获取字段枚举器
                                                                     //枚举每个字段
                    foreach (var enumElement in enumElementArray)
                    {
                        switch (enumElement.Name)
                        {
                            case "GUILDS"://频道事件
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.GUILDS;
                                break;
                            case "GUILD_MEMBERS"://频道成员事件
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.GUILD_MEMBERS;
                                break;
                            case "GUILD_MESSAGES"://频道消息事件，仅限私域可订阅
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.GUILD_MESSAGES;
                                break;
                            case "GUILD_MESSAGE_REACTIONS"://表情表态事件
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.GUILD_MESSAGE_REACTIONS;
                                break;
                            case "DIRECT_MESSAGE"://私信会话事件
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.DIRECT_MESSAGE;
                                break;
                            case "MESSAGE_AUDIT"://消息审核事件
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.MESSAGE_AUDIT;
                                break;
                            case "FORUMS_EVENT"://论坛事件,仅私域机器人可订阅
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.FORUMS_EVENT;
                                break;
                            case "AUDIO_ACTION"://音频事件
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.AUDIO_ACTION;
                                break;
                            case "PUBLIC_GUILD_MESSAGES"://公域消息事件
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.PUBLIC_GUILD_MESSAGES;
                                break;
                            case "INTERACTION"://互动事件
                                if (enumElement.Value.GetBoolean())
                                    intents += (int)Sirius.intentsEnum.SiriusIntentEnum.INTERACTION;
                                break;
                        }
                    }
                }
                sr.Close();
            }
            else
            {
                LogWar("初始化", "配置文件不存在，生成默认配置文件");
                //如果文件不存在则创建默认订阅配置文件，默认订阅所有事件，公域机器人需进行调整，否则会鉴权失败
                var file = File.Create("Config.json");
                StreamWriter sw = new StreamWriter(file);
                sw.Write("{\r\n\t\"httpPort\":\"2345\",\r\n\t\"WSport\":\"6789\",\r\n\t\"token\":\"123456\",\r\n\t\"intents\":[\r\n\t\t{\r\n\t\t\t\"GUILDS\":true,\r\n\t\t\t\"GUILD_MEMBERS\":true,\r\n\t\t\t\"GUILD_MESSAGES\":false,\r\n\t\t\t\"GUILD_MESSAGE_REACTIONS\":true,\r\n\t\t\t\"DIRECT_MESSAGE\":true,\r\n\t\t\t\"INTERACTION\":true,\r\n\t\t\t\"MESSAGE_AUDIT\":true,\r\n\t\t\t\"FORUMS_EVENT\":false,\r\n\t\t\t\"AUDIO_ACTION\":true,\r\n\t\t\t\"PUBLIC_GUILD_MESSAGES\":true\r\n\t\t}\r\n\t]\r\n}");
                sw.Close();
            }
        }
        //发送心跳包
        public static void send_HeartBeatPack(object sender,System.Timers.ElapsedEventArgs args)
        {
            //异步发送心跳包
            Task.Run(async () =>
            {
                SendMsg(SiriusWebSocketClient.SiriusClient, CreateHeart_BeatPack(s));
            });
        }

        //加载SiriusAPI.dll
        public static bool isExistSiriusAPI()
        {
            var dll =kernel32.LoadLibraryA("SiriusAPI.dll");
            if ((int)dll == 0)
            {
                return false;
            }
            SiriusApiManager.InitSiriusApi(dll);
            return true;
        }

        //登陆Bot
        public static void LoginBot()
        {
            //判断配置文件是否存在
            if(!File.Exists("bot.json"))
            {
                //首次登陆需要输入账号密码
                while (true)
                {
                    Console.Write("请输入BotId:");
                    BotId = Console.ReadLine();
                    Console.Write("请输入Token:");
                    Token = Console.ReadLine();
                    if (SiriusWebSocketClient.SiriusLogin(BotId, Token, false))
                    {
                        var file = File.Create("bot.json");
                        StreamWriter sw = new StreamWriter(file);
                        sw.Write(JsonSerializer.Serialize(new BotInfo(BotId, Token)));
                        sw.Close();
                        break;
                    }else
                    {
                        break;
                    }
                }
                
            }else
            {
                StreamReader sr = new StreamReader("bot.json");
                string BotJson = sr.ReadToEnd();
                var json = JsonDocument.Parse(BotJson);
                BotId = json.RootElement.GetProperty("bot_id").GetString();
                Token = json.RootElement.GetProperty("token").GetString();
                SiriusWebSocketClient.SiriusLogin(BotId, Token,false);
            }
        }

        //Sirius初始化
        public static void InitSirius()
        {
            LogOut("Sever", "********** 欢迎使用Sirius! **********");
            intentsInit();
            if (isExistSiriusAPI())
            {
                LogSuc("Server", "SiriusAPI加载成功！");

                ApplicationManager.LoadApplication();
                //启动重连定时器
                Reconnect_Timer.AutoReset = true;
                Reconnect_Timer.Elapsed += new System.Timers.ElapsedEventHandler(close_Reconnect);
                Reconnect_Timer.Start();

                //启动WebSocket服务端
                Sirius.WebSocket.WebSocketAPI.WebSocketServerAPI.InitWebSocketServer();
                Sirius.SiriusAPI.SiriusHttpServer.httpServerInit();
                Sirius.SiriusAPI.SiriusHttpServer.httpAccept();



            }
            else
            {
                LogErr("Server", "SiriusAPI加载失败！按任意键退出.....");
                Console.ReadKey();
                Environment.Exit(0);
            }

        }

        //卸载插件
        public static void removeApplication(int appIndex)
        {
            try
            {
                if (kernel32.FreeLibrary(ApplicationManager.apps[appIndex].instance))
                {
                    LogSuc("应用卸载:", "应用:" + ApplicationManager.apps[appIndex].appInfo.App_Name + "卸载成功!");
                    new FileInfo(ApplicationManager.apps[0].AppPath).Delete();
                    ApplicationManager.apps.RemoveAt(appIndex);

                }
                else
                {
                    LogWar("应用卸载:", "应用:" + ApplicationManager.apps[appIndex].appInfo.App_Name + "卸载失败!");
                }
            }catch (Exception ex)
            {
                LogErr("应用卸载", "应用ID输入不正确！" + ex.Message);
            }
        }
        //加载应用
        public static void loadApplication()
        {
           try
            {
                Console.WriteLine("请将应用拖入到本窗口后,按下回车键");
                string AppPath = Console.ReadLine();
                FileInfo addFile = new FileInfo(AppPath);
                if (addFile.Exists)
                {
                    if (!new FileInfo("Plugin\\" + addFile.Name).Exists)
                    {

                        ApplicationManager.loadOneApplication(addFile.CopyTo("Plugin\\" + addFile.Name));
                    }
                    else
                    {
                        LogErr("应用加载失败！", "文件" + "[" + addFile.Name + "]" + "已存在,请删除后再试");
                    }
                }
                else
                {
                    LogErr("应用加载失败！", "指定应用不存在，请重新输入");
                }
            }catch(Exception ex)
            {
                LogErr("应用加载", "请拖入正确的Sirius应用,或目录不正确...");
            }
        }

        //日志写入
        public static void logWriter(string fileName, string data)
        {
            //判断日志文件夹是否存在
            if (!Directory.Exists("log"))
                Directory.CreateDirectory("log");
            //判断日志文件是否存在，不存则创建
            if (!File.Exists("log\\" + fileName))
                File.Create("log\\" + fileName).Close();
            
            

            var logFile = new StreamReader("log\\" + fileName);
            //获取当前日志的所有数据
            string nowData = logFile.ReadToEnd();
            //关闭文件，解除文件占用
            logFile.Close();
            //获取文件的输出流对象
            var log = new StreamWriter("log\\"+fileName);
            log.WriteLine(nowData+"[" + DateTime.Now.ToString("HH:mm:ss") + "日志内容]："+data);
            log.Close();
        }

        public static void close_Reconnect(object sender,System.Timers.ElapsedEventArgs args)
        {
            if(Sirius.WebSocket.SiriusWebSocketClient.SiriusClient.State != WebSocketState.Open)
            {
                Sirius.WebSocket.SiriusWebSocketClient.SiriusClient = new ClientWebSocket();
                Sirius.WebSocket.SiriusWebSocketClient.SiriusClientConnect();
                Sirius.WebSocket.MessageManager.MessagePush.session_id = null;
            }   
        }
    }
    public class BotInfo
    {
        public BotInfo(string BotId,string token)
        {
            this.BotId = BotId;
            this.Token = token;
        }
        //BotId
        [JsonPropertyName("bot_id")]
        public string BotId { get; set; }
        
        //BotToken
        [JsonPropertyName("token")]
        public string Token { get; set; }
    }

    public static class HttpUtil
    {
        public static Object readData(Stream InputStream)
        {
            int count = 0;
            byte[] buffer = new byte[1024];
            StringBuilder builder = new StringBuilder();
            while ((count = InputStream.Read(buffer, 0, 1024)) > 0)
            {
                builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
            }
            InputStream.Close();
            return builder.ToString();
        }
    }
}